#include "MeshGroup.h"
#include "Fysics/Renderer/Renderer.h"

#include <glm/gtc/matrix_transform.hpp>

namespace Fysics
{
	MeshGroup::MeshGroup() : m_Name(""), m_OriginModelMat(glm::mat4(1)),
		m_Position(glm::vec3(0)), m_Rotation(glm::vec3(0)), m_Scaling(glm::vec3(1)),
		m_Parent(nullptr)
	{
	}

	MeshGroup::~MeshGroup()
	{
		for (Mesh* mesh : m_Meshes)
		{
			delete mesh;
		}
		for (MeshGroup* child : m_Children)
		{
			delete child;
		}
	}

	void MeshGroup::AddMesh(Mesh* mesh)
	{
		m_Meshes.push_back(mesh);
	}

	Mesh* MeshGroup::GetMesh(int index)
	{
		if (index >= m_Meshes.size())
		{
			return nullptr;
		}
		return m_Meshes[index];
	}

	void MeshGroup::AddChild(MeshGroup* child)
	{
		if (child == nullptr)
			return;
		m_Children.push_back(child);
	}

	MeshGroup* MeshGroup::GetChild(int index) const
	{
		if (index >= m_Children.size())
			return nullptr;
		return m_Children.at(index);
	}

	glm::mat4 MeshGroup::GetModelMatrix() const
	{
		glm::mat4 model(1);
		glm::mat4 transform = glm::translate(m_OriginModelMat, m_Position)
			* glm::rotate(model, glm::radians(m_Rotation.x), glm::vec3(1.0f, 0.0f, 0.0f))
			* glm::rotate(model, glm::radians(m_Rotation.y), glm::vec3(0.0f, 1.0f, 0.0f))
			* glm::rotate(model, glm::radians(m_Rotation.z), glm::vec3(0.0f, 0.0f, 1.0f))
			* glm::scale(model, m_Scaling);
		return transform;
	}

	void MeshGroup::Draw(const glm::mat4& itemModelMat)
	{
		glm::mat4 transform = itemModelMat * GetModelMatrix();
		Renderer::SubmitModelMatrix(transform);
		for (Mesh* mesh : m_Meshes)
		{
			mesh->Draw();
		}
		for (MeshGroup* child : m_Children)
		{
			child->Draw(transform);
		}
	}
}